package com.htstar.ovms.device.gateway.controller;

import com.htstar.ovms.common.core.constant.SecurityConstants;
import com.htstar.ovms.common.core.util.R;
import com.htstar.ovms.common.security.annotation.Inner;
import com.htstar.ovms.device.api.entity.DeviceOta;
import com.htstar.ovms.device.api.feign.DeviceMsgFeign;
import com.htstar.ovms.device.api.wrapper.MessageWrapper;
import com.htstar.ovms.device.api.wrapper.OTAData;
import com.htstar.ovms.device.gateway.core.connector.tcp.TcpConnector;
import com.htstar.ovms.device.gateway.core.connector.tcp.forCommandUtils.util.ObdUtil;
import com.htstar.ovms.device.gateway.core.notify.NotifyProxy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/OTAUpdata")
public class OTAGatewayUpdateController {

    @Autowired
    TcpConnector tcpConnector;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    DeviceMsgFeign deviceMsgFeign;


    @Inner(value = false)
    @RequestMapping("update")
    public R OTA(@RequestBody OTAData req) throws Exception {
        log.debug("开始升级");
//      NotifyProxy notifyProxy = new NotifyProxy(tcpConnector);
        MessageWrapper obdGpsMsg = new MessageWrapper();
        obdGpsMsg.setDeviceSn(req.getDeviceSn());
        obdGpsMsg.setMessageType(MessageWrapper.MessageType.SEND);
        obdGpsMsg.setSeq(6L);
        obdGpsMsg.setBody(hexStrToByteArray(req.getData()));
//      int notify = notifyProxy.notify(obdGpsMsg, 1000 * 60 * 10);//单位毫秒
        tcpConnector.responseSendMessage(obdGpsMsg);
        log.debug("升级结束");
        return R.ok();
    }

    /**
     * 对在线设备直接下发
     *
     * @param req
     * @return
     * @throws Exception
     */
    @Inner(value = false)
    @RequestMapping("updateBatch")
    public R updateBatch(@RequestBody OTAData req) throws Exception {
        List<String> deviceSnList = req.getDeviceSnList();
        log.info("开始批量升级，设备号{}", deviceSnList.toString());
        String data = req.getData();
        String otaData = data;
        //最多尝试下发3次指令
        for (int i = 0; i < 3; i++) {
            Iterator<String> iterator = deviceSnList.iterator();
            while (iterator.hasNext()) {
                String deviceSn = iterator.next();
                try {
                    MessageWrapper msgWrapper = new MessageWrapper();
                    msgWrapper.setDeviceSn(deviceSn);
                    msgWrapper.setMessageType(MessageWrapper.MessageType.SEND);
                    msgWrapper.setSeq(6L);
                    msgWrapper.setBody(hexStrToByteArray(otaData));
//      int notify = notifyProxy.notify(msgWrapper, 1000 * 60 * 10);//单位毫秒
                    tcpConnector.responseSendMessage(msgWrapper);
                    log.info("OTA升级指令下发情况：设备号{}已下发，数据{}", deviceSn, otaData);
                } catch (Exception e) {
                    log.info("OTA升级指令下发情况：{}不在线", deviceSn);
                    //更新下发失败次数
                    OTAData otaData1 = new OTAData();
                    otaData1.setDeviceSn(deviceSn);
                    deviceMsgFeign.OTAupdateState(otaData1, SecurityConstants.FROM_IN);//记录失败次数
                    deviceSnList.add(deviceSn);
                }
                iterator.remove();
            }
        }
        return R.ok();
    }

    public static byte[] hexStrToByteArray(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[str.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = str.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }

}
